package Simulator;

import java.util.List;
import java.util.Iterator;
import java.util.Random;

public class Fox extends AbstactAnimal {
	// number of steps a fox can go before it has to eat again.
	private static final int RABBIT_FOOD_VALUE = 4;
	// the number of steps a fox can go before it has to eat again.
	private static final int BIRD_FOOD_VALUE = 2;
	// A shared random number generator to control breeding.
	private static final Random rand = new Random();
	// Variables to set the maxAge, breedingAge, probability and litter
	private static int age = 150;
	private static int breed = 10;
	private static double probability = 0.20;
	private static int litter = 5;

	public Fox(boolean randomAge) {
		super();
		maxAge = age;
		breedingAge = breed;
		breedingProbability = probability;
		maxLitterSize = litter;

		if (randomAge) {
			setAge(rand.nextInt(maxAge));
			foodLevel = rand.nextInt(RABBIT_FOOD_VALUE);
		} else {
			// leave age at 0
			foodLevel = RABBIT_FOOD_VALUE;
		}
	}

	public static void setUp(int maxAge, int breedAge, double prob,
			int maxLitter) {
		age = maxAge;
		breed = breedAge;
		probability = prob;
		litter = maxLitter;
	}

	public void act(Field currentField, Field updatedField,
			List<ActorInterface> newActors) {
		incrementAge();
		incrementHunger();
		if (isAlive()) {
			// New foxes are born into adjacent locations.
			int births = breed();
			for (int b = 0; b < births; b++) {
				Fox newFox = new Fox(false);
				newActors.add(newFox);
				newFox.setLocation(updatedField
						.randomAdjacentLocation(getLocation()));
				updatedField.place(newFox);
			}
			// Move towards the source of food if found.
			Location newLocation = findFood(currentField, getLocation());
			if (newLocation == null) { // no food found - move randomly
				newLocation = updatedField.freeAdjacentLocation(getLocation());
			}
			if (newLocation != null) {
				setLocation(newLocation);
				updatedField.place(this); // sets location
			} else {
				// can neither move nor stay - overcrowding
				setDead();
			}
		}
	}

	public Location findFood(Field field, Location location) {
		Iterator<Location> adjacentLocations = field
				.adjacentLocations(location);
		while (adjacentLocations.hasNext()) {
			Location where = adjacentLocations.next();
			ActorInterface actor = field.getActorAt(where);
			if (actor instanceof Bird) {
				Bird bird = (Bird) actor;
				if (bird.isAlive()) {
					bird.setDead();
					foodLevel = BIRD_FOOD_VALUE;
					return where;
				}
			} else if (actor instanceof Rabbit) {
				Rabbit rabbit = (Rabbit) actor;
				if (rabbit.isAlive()) {
					rabbit.setDead();
					foodLevel = RABBIT_FOOD_VALUE;
					return where;
				}
			}
		}
		return null;
	}

	public String toString() {
		return "Fox, age " + getAge();
	}
}
